﻿using System;
using System.Collections.Generic;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKRevitDimensionText.OneKeyPlanDim.LevelDim;
using YJKRevitDimensionText.OneKeyPlanDim.Utility;
using YJKRevitDimensionText.VerticalAutoDim.OutWallSearch;

namespace YJKRevitDimensionText.OneKeyPlanDim.DimesionDataEx
{
	public class WallDataConstructor
	{
		public WallDataConstructor(UIApplication uiApp)
		{
			this.m_uiApp = uiApp;
			this.m_doc = this.m_uiApp.ActiveUIDocument.Document;
			this.InitData();
		}

		public List<WallDataEx> GetOutWallData()
		{
			return this.m_lstOutWallData;
		}

		public List<WallDataEx> GetInWallData()
		{
			return this.m_lstInWallData;
		}

		public XYZ GetCenter()
		{
			return this.m_ptCenter;
		}

		private void InitData()
		{
			this.m_ptCenter = GeometryHelper.GeometricCenterByLstCvPoint(KeyComponent.GetInstance().m_lstOutWallCurves);
			this.InitOutWallData();
			this.InitInWallData();
			this.InitDoorWinData();
			this.TryMegerMultichannelWall();
		}

		private void InitDoorWinData()
		{
			List<FamilyInstance> list = new List<FamilyInstance>();
			list.AddRange(KeyComponent.GetInstance().m_lstDoor);
			list.AddRange(KeyComponent.GetInstance().m_lstWindow);
			Dictionary<ElementId, List<DoorWinDataEx>> dictionary = new Dictionary<ElementId, List<DoorWinDataEx>>();
			foreach (FamilyInstance familyInstance in list)
			{
				if (familyInstance != null && familyInstance.Location != null)
				{
					DoorWinDataEx item = new DoorWinDataEx(this.m_uiApp, familyInstance, familyInstance.Host.Id);
					List<DoorWinDataEx> list2 = null;
					if (dictionary.TryGetValue(familyInstance.Host.Id, out list2))
					{
						list2.Add(item);
					}
					else
					{
						list2 = new List<DoorWinDataEx>();
						list2.Add(item);
						dictionary.Add(familyInstance.Host.Id, list2);
					}
				}
			}
			foreach (WallDataEx wallDataEx in this.m_lstOutWallData)
			{
				List<DoorWinDataEx> doorWinDataEx = null;
				if (dictionary.TryGetValue(wallDataEx.WallId, out doorWinDataEx))
				{
					wallDataEx.SetDoorWinDataEx(doorWinDataEx);
				}
			}
			foreach (WallDataEx wallDataEx2 in this.m_lstInWallData)
			{
				List<DoorWinDataEx> doorWinDataEx2 = null;
				if (dictionary.TryGetValue(wallDataEx2.WallId, out doorWinDataEx2))
				{
					wallDataEx2.SetDoorWinDataEx(doorWinDataEx2);
				}
			}
		}

		private void InitOutWallData()
		{
			for (int i = 0; i < KeyComponent.GetInstance().m_lstOutWallData.Count; i++)
			{
				OutWallData outWallData = KeyComponent.GetInstance().m_lstOutWallData[i];
				if (outWallData != null && outWallData.Element != null)
				{
					Wall wall = outWallData.Element as Wall;
					if (wall != null)
					{
						this.m_lstOutWallId.Add(wall.Id);
						WallDataEx wallDataEx = new WallDataEx(wall, true, outWallData.Orientation, outWallData.Curve);
						if (i == 0)
						{
							wallDataEx.ConnectWall.Add(KeyComponent.GetInstance().m_lstOutWallData[i + 1].Element.Id);
							wallDataEx.ConnectWall.Add(KeyComponent.GetInstance().m_lstOutWallData[KeyComponent.GetInstance().m_lstOutWallData.Count - 1].Element.Id);
						}
						else if (i == KeyComponent.GetInstance().m_lstOutWallData.Count - 1)
						{
							wallDataEx.ConnectWall.Add(KeyComponent.GetInstance().m_lstOutWallData[i - 1].Element.Id);
							wallDataEx.ConnectWall.Add(KeyComponent.GetInstance().m_lstOutWallData[0].Element.Id);
						}
						else
						{
							wallDataEx.ConnectWall.Add(KeyComponent.GetInstance().m_lstOutWallData[i + 1].Element.Id);
							wallDataEx.ConnectWall.Add(KeyComponent.GetInstance().m_lstOutWallData[i - 1].Element.Id);
						}
						this.m_lstOutWallData.Add(wallDataEx);
					}
				}
			}
		}

		private void InitInWallData()
		{
			using (List<Wall>.Enumerator enumerator = KeyComponent.GetInstance().m_lstWall.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					Wall wall = enumerator.Current;
					ElementId elementId = this.m_lstOutWallId.Find((ElementId e) => e == wall.Id);
					if (!(elementId != null) || elementId.IntegerValue != wall.Id.IntegerValue)
					{
						WallDataEx item = new WallDataEx(wall, false, null, null);
						this.m_lstInWallData.Add(item);
					}
				}
			}
			this.InitInWallByInOutWall();
		}

		private void InitInWallByInOutWall()
		{
			Dictionary<ElementId, List<OutWallData>> dictionary = new Dictionary<ElementId, List<OutWallData>>();
			foreach (OutWallData outWallData in KeyComponent.GetInstance().m_lstOutWallData)
			{
				if (outWallData != null && outWallData.Element != null && !(outWallData.Element.Id == ElementId.InvalidElementId))
				{
					List<OutWallData> list = null;
					if (dictionary.TryGetValue(outWallData.Element.Id, out list))
					{
						list.Add(outWallData);
					}
					else
					{
						list = new List<OutWallData>();
						list.Add(outWallData);
						dictionary.Add(outWallData.Element.Id, list);
					}
				}
			}
			foreach (KeyValuePair<ElementId, List<OutWallData>> keyValuePair in dictionary)
			{
				List<OutWallData> value = keyValuePair.Value;
				if (value.Count != 0)
				{
					List<Line> list2 = new List<Line>();
					foreach (OutWallData outWallData2 in value)
					{
						Line line = outWallData2.Curve as Line;
						if (!(line == null))
						{
							list2.Add(line);
						}
					}
					Wall wall = value[0].Element as Wall;
					SplitLine splitLine = new SplitLine((wall.Location as LocationCurve).Curve as Line, list2);
					if (splitLine.LstLineResult.Count != 0)
					{
						foreach (Line cvProfileLine in splitLine.LstLineResult)
						{
							WallDataEx item = new WallDataEx(wall, false, value[0].Orientation, cvProfileLine);
							this.m_lstInWallData.Add(item);
						}
					}
				}
			}
		}

		private void TryMegerMultichannelWall()
		{
			foreach (WallDataEx wallDataEx in this.m_lstOutWallData)
			{
				for (int i = 0; i < this.m_lstInWallData.Count; i++)
				{
					if (wallDataEx.TryMegerMultichannelWall(this.m_lstInWallData[i]))
					{
						this.m_lstInWallData.RemoveAt(i);
						i--;
					}
				}
			}
			for (int j = 0; j < this.m_lstInWallData.Count; j++)
			{
				for (int k = j + 1; k < this.m_lstInWallData.Count; k++)
				{
					if (this.m_lstInWallData[j].TryMegerMultichannelWall(this.m_lstInWallData[k]))
					{
						this.m_lstInWallData.RemoveAt(k);
						k--;
					}
				}
			}
			if (this.m_lstOutWallData.Count < 3)
			{
				return;
			}
			for (int l = 0; l < this.m_lstOutWallData.Count; l++)
			{
				if (l == this.m_lstOutWallData.Count - 1)
				{
					this.m_lstOutWallData[l].TryCutting2WallInLineAndOutLine(this.m_lstOutWallData[0]);
				}
				else
				{
					this.m_lstOutWallData[l].TryCutting2WallInLineAndOutLine(this.m_lstOutWallData[l + 1]);
				}
			}
		}

		private List<WallDataEx> m_lstOutWallData = new List<WallDataEx>();

		private List<WallDataEx> m_lstInWallData = new List<WallDataEx>();

		private XYZ m_ptCenter;

		private List<ElementId> m_lstOutWallId = new List<ElementId>();

		private Document m_doc;

		private UIApplication m_uiApp;
	}
}
